package service

import (
	"saas-app/app/dao"
	"saas-app/library/util"

	"github.com/gogf/gf/container/gset"
	"github.com/gogf/gf/database/gdb"
)

type RoleRepository interface {
	GetAllPowerCode(user_id uint) []string
	GetUserRoleId(user_id uint) []uint
	GetPowerCodeByRoleId([]uint) []string
	GetRoleList() *[]map[string]interface{}
	GetPowerTree() []map[string]interface{}
	GetIdsByCodes(codes []string) []uint
}

type role struct{}

func RoleService() RoleRepository {
	return &role{}
}

func (r role) GetAllPowerCode(user_id uint) []string {
	if result, err := dao.Power.Array("code"); err != nil {
		panic(err)
	} else {
		return util.AliceGvarToString(result)
	}
}

func (r role) GetIdsByCodes(codes []string) []uint {
	if result, err := dao.Power.WhereIn("code", codes).Array("id"); err != nil {
		panic(err)
	} else {
		return util.AliceGvarToUint(result)
	}
}

func (r role) GetUserRoleId(user_id uint) []uint {

	if result, err := dao.RoleUser.Where("user_id=?", user_id).Array("role_id"); err != nil {
		panic(err)
	} else {
		return util.AliceGvarToUint(result)
	}
}

func (r role) GetPowerCodeByRoleId(roleIds []uint) []string {

	// 先拿到所有角色的权限id
	powerIds, err := dao.RolePower.WhereIn("role_id", roleIds).Array("power_id")

	if err != nil {
		panic(err)
	}

	// 去重
	s := gset.NewFrom(powerIds)
	slices := s.Slice()

	// 通过权限id  拿code
	if codes, err := dao.Power.WhereIn("id", slices).Array("code"); err != nil {
		panic(err)
	} else {
		return util.AliceGvarToString(codes)
	}
}

func (r role) GetRoleList() *[]map[string]interface{} {

	result, err := dao.Roles.All()

	if err != nil {
		panic(err)
	}

	list := result.List()

	ids := []uint{}
	for _, role := range list {
		ids = append(ids, uint(role["id"].(int)))
	}

	power_list, err := dao.RolePower.WhereIn("role_id", ids).LeftJoin("power", "role_power.power_id = power.id").Fields("role_power.role_id", "power.code").All()

	if err != nil {
		panic(err)
	}

	power_list_arr := power_list.List()

	for _, item := range list {
		ilist := []string{}
		for _, v := range power_list_arr {
			if item["id"].(int) == v["role_id"].(int) {
				ilist = append(ilist, v["code"].(string))
			}
		}
		item["power_list"] = ilist
	}

	return &list
}

func (r role) GetPowerTree() []map[string]interface{} {

	result, err := dao.Power.All()

	if err != nil {
		panic(err)
	}
	return createTree(&result)
}

// 创建权限树
func createTree(powers *gdb.Result) []map[string]interface{} {

	list := powers.List()
	tree := []map[string]interface{}{}
	children := []map[string]interface{}{}

	for _, v := range list {
		v["children"] = []map[string]interface{}{}
		if v["parent_id"] == 0 {
			tree = append(tree, v)
		} else {
			children = append(children, v)
		}
	}

	for _, child := range children {
		formatTree(&tree, child)
	}

	return tree
}

// // 格式化权限树
func formatTree(tree *[]map[string]interface{}, power map[string]interface{}) {
	for _, v := range *tree {
		children := v["children"].([]map[string]interface{})
		if v["id"] == power["parent_id"] {
			v["children"] = append(children, power)
		} else {
			if len(children) > 0 {
				formatTree(tree, power)
			}
		}
	}
}
